#include "Font.h"
#include "Texture.h"
#include "TextureResourceManager.h"
#include <fstream>
using namespace Graphics;

Font::Font(void)
	:mFont(NULL),
	 mFontTexture(NULL)
{
}

Font::~Font(void)
{
	Deinitialize();
}

bool Font::Initialize(const char* fontFilename, const char* textureFilename)
{
	bool result = LoadFontData(fontFilename);
	if(result)
	{
		//mFontTexture = TextureResourceManager::GetInstance()->GetResource(textureFilename);
		mFontTexture = MY_NEW(Memory::HID_Rendering, "Font Texture") Texture("Font Texture", textureFilename);
		if(!mFontTexture)
		{
			result = false;
		}
		result = mFontTexture->Initialize();
	}
	return result;
#ifdef DX_9
	Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	HRESULT result = D3DXCreateFont(nDevice->GetDevice(),		// the D3D Device
								   30,							// font height
								   0,							// default font width
								   FW_NORMAL,					// font weight
								   1,							// not using MipLevels
								   false,						// italic font
								   DEFAULT_CHARSET,				// default character set
								   OUT_DEFAULT_PRECIS,			// default OutputPrecision,
								   ANTIALIASED_QUALITY,				// default Quality
								   DEFAULT_PITCH | FF_DONTCARE, // default pitch and family
								   "Arial",						// use Facename Arial
								   &mFont );					// the font object
	CHECK(result);
#endif
}

void Font::Deinitialize()
{
	if(mFontTexture)
	{
		MY_DELETE(mFontTexture);
		mFontTexture = NULL;
	}
}

bool Font::LoadFontData(const char* fileName)
{
	// Create the font spacing buffer.
	mFont = new FontType[FONT_NUMBER];
	
	std::ifstream fin;
	fin.open(fileName);
	if(fin.fail())
	{
		return false;
	}

	char temp;
	for(int i = 0; i < FONT_NUMBER; i++)
	{
		fin.get(temp);
		while(temp != ' ')
		{
			fin.get(temp);
		}
		fin.get(temp);
		while(temp != ' ')
		{
			fin.get(temp);
		}

		fin >> mFont[i].left;
		fin >> mFont[i].right;
		fin >> mFont[i].size;
	}

	fin.close();

	return true;
}
#ifdef DX_9
void Font::Render(const std::string& text, int x, int y)
{
	RECT textbox;
	Graphics::D3DDevice* nDevice = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();

	SetRect(&textbox, x, y,nDevice->GetResolutionInfo().ScreenWidth, nDevice->GetResolutionInfo().ScreenHeight);
	mFont->DrawTextA(NULL,text.c_str(),strlen(text.c_str()),&textbox, DT_LEFT | DT_TOP, D3DCOLOR_XRGB(255,255,255));
}
#endif

void Font::BuildVertexArray(void* vertices, const char* sentence, float drawX, float drawY)
{
	FontVertexType* vertexPtr = (FontVertexType*) vertices;

	int numLetters = (int) strlen(sentence);
	int index = 0;

	for(int i = 0; i < numLetters; i++)
	{
		int letter = ((int) sentence[i]) - FONT_LETTER_WIDTH;
		if(letter == 0)
		{
			drawX = drawX + 3.0f;
		}
		else
		{
			// First triangle in quad.
			vertexPtr[index].position = D3DXVECTOR3(drawX, drawY, 0.0f);  // Top left.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].left, 0.0f);
			index++;

			vertexPtr[index].position = D3DXVECTOR3((drawX + mFont[letter].size), (drawY - FONT_OFFSET), 0.0f);  // Bottom right.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].right, 1.0f);
			index++;

			vertexPtr[index].position = D3DXVECTOR3(drawX, (drawY - FONT_OFFSET), 0.0f);  // Bottom left.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].left, 1.0f);
			index++;

			// Second triangle in quad.
			vertexPtr[index].position = D3DXVECTOR3(drawX, drawY, 0.0f);  // Top left.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].left, 0.0f);
			index++;

			vertexPtr[index].position = D3DXVECTOR3(drawX + mFont[letter].size, drawY, 0.0f);  // Top right.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].right, 0.0f);
			index++;

			vertexPtr[index].position = D3DXVECTOR3((drawX + mFont[letter].size), (drawY - FONT_OFFSET), 0.0f);  // Bottom right.
			vertexPtr[index].texture = D3DXVECTOR2(mFont[letter].right, 1.0f);
			index++;

			// Update the x location for drawing by the size of the letter and one pixel.
			drawX = drawX + mFont[letter].size + 1.0f;
		}
	}
}

Texture* Font::GetTexture()
{
	return mFontTexture;
}